<template>
  <lay-container fluid class="container-box">
    <!--查询条件-->
    <lay-card>
      <lay-form :model="searchModel" ref="searchForm" size="sm" labelWidth="80" class="search-form">
        <lay-form-item label="角色标识" prop="roleCode" mode="inline" >
          <lay-input v-model="searchModel.roleCode" placeholder="请输入" :allow-clear="true"/>
        </lay-form-item>
        <lay-form-item label="角色名称" prop="roleName" mode="inline">
          <lay-input v-model="searchModel.roleName" placeholder="请输入" :allow-clear="true"/>
        </lay-form-item>
        <lay-form-item mode="inline" v-permission="['sys:role:list']">
          <lay-button type="primary" @click="search" prefix-icon="layui-icon-search">
            查询
          </lay-button>
          <lay-button @click="searchReset" prefix-icon="layui-icon-refresh">
            重置 
          </lay-button>
        </lay-form-item>
      </lay-form>
   
      <!-- table表格 -->
      <div class="table-box">
        <lay-table
          :page="page"
          :columns="columns"
          :id="id"
          :loading="loading"
          :default-toolbar="['filter','print']"
          :data-source="dataSource"
          :autoColsWidth="true"
          :resize="true"
          v-model:selected-key="selectedKey"
          @change="search"
          @sortChange="sortChange">

          <!--操作列-->
          <template v-slot:operator="{ row }">
            <lay-space>
              <lay-button v-permission="['sys:role:info']" @click="toInfo(row)" prefix-icon="layui-icon-tips" type="normal" size="sm">
                详情
              </lay-button>
              <lay-dropdown updateAtScroll>
                <lay-button type="primary" suffix-icon="layui-icon-down" size="sm">更多</lay-button>
                <template #content>
                    <lay-dropdown-menu>
                      <lay-dropdown-menu-item v-permission="['sys:role:edit']" @click="toSave('编辑', row)">
                        <template #prefix><lay-icon type="layui-icon-edit"/></template>
                        <template #default>编辑</template>
                      </lay-dropdown-menu-item>
                      <lay-dropdown-menu-item v-permission="['sys:role:remove']" @click="remove(row)">
                        <template #prefix><lay-icon type="layui-icon-delete"/></template>
                        <template #default>删除</template>
                      </lay-dropdown-menu-item>
                      <lay-dropdown-menu-item v-permission="['sys:role:menu']" @click="toAssigningMenus(row)">
                        <template #prefix><lay-icon type="layui-icon-menu-fill"/></template>
                        <template #default>分配菜单</template>
                      </lay-dropdown-menu-item>
                    </lay-dropdown-menu>
                </template>
              </lay-dropdown>
            </lay-space>
          </template>

          <!--工具栏-->
          <template v-slot:toolbar>
            <lay-button v-permission="['sys:role:add']" @click="toSave('新增')" type="primary" size="sm">
              <lay-icon class="layui-icon-addition"/>
              新增
            </lay-button>
            <lay-button v-permission="['sys:role:export']" @click="exportData" size="sm">
              <lay-icon class="layui-icon-export"/>
              导出
            </lay-button>
          </template>
        </lay-table>
      </div>
    </lay-card>

    <!-- 保存窗口 -->
    <lay-layer v-model="visibleSaveLayer" :title="saveLayerTitle" :btn="saveLayerBtn" :area="['730px', '430px']" :maxmin="true">
        <lay-form class="model-form" :model="saveModel" ref="saveForm" :rules="saveFormRules" size="sm" label-width="80">

          <lay-form-item v-if="!saveModel.id" label="角色标识" prop="roleCode" mode="inline" :required="true">
            <lay-input v-model="saveModel.roleCode" placeholder="请输入"/>
          </lay-form-item>

          <lay-form-item label="角色名称" prop="roleName" mode="inline" :required="true">
            <lay-input v-model="saveModel.roleName" placeholder="请输入"/>
          </lay-form-item>

          <lay-form-item label="备注" prop="remark">
            <lay-textarea placeholder="请输入备注" v-model="saveModel.remark"/>
          </lay-form-item>

        </lay-form>
    </lay-layer>

    <!-- 详情窗口 -->
    <lay-layer v-model="visibleInfoLayer" title="详情" :btn="infoLayerBtn" :area="['730px', '430px']" :maxmin="true" >
        <lay-form class="model-form" :model="infoModel" size="sm" label-width="100" :pane="true">

          <lay-form-item label="角色标识" prop="roleCode" mode="inline">
            <lay-input v-model="infoModel.roleCode" readonly/>
          </lay-form-item>

          <lay-form-item label="角色姓名" prop="roleName" mode="inline" >
            <lay-input v-model="infoModel.roleName" readonly />
          </lay-form-item>

          <lay-form-item label="类型" prop="typeName" mode="inline">
            <lay-input v-model="infoModel.typeName" readonly />
          </lay-form-item>
          
          <lay-form-item label="创建时间" prop="createTime" mode="inline">
            <lay-input v-model="infoModel.createTime" readonly />
          </lay-form-item>

          <lay-form-item label="备注" prop="remark">
            <lay-textarea v-model="infoModel.remark" :disabled="true" />
          </lay-form-item>

        </lay-form>
    </lay-layer>
    <!-- 分配角色窗口 -->
    <lay-layer v-model="visibleAssigningMenusLayer" title="分配角色" :btn="assigningMenusLayerBtn" :area="['400px', '600px']" :maxmin="true" >
        <lay-tree
          :data="menuList"
          :tail-node-icon="false"
          :showCheckbox="true"
          v-model:checkedKeys="assignedMenuModel.menuIds"
          v-model:expandKeys="menuIdsList">
        </lay-tree>
    </lay-layer>
  </lay-container>
</template>
<script setup lang="ts">

import { ref, reactive ,onMounted} from 'vue'
import { layer} from '@layui/layui-vue'
import { pageApi,saveApi,removeApi,infoApi,exportApi,queryAssignedMenuApi,assigningMenusApi} from '../../../api/module/system/sys-role'
import { treeApi} from '../../../api/module/system/sys-menu'
import { Rules} from 'async-validator';

//加载函数
onMounted(() => {
  //查询数据
  search();
})

//主键id
const id = ref<string>("id")
//表格数据源
const dataSource = ref<any[]>([])
//选中数据行id
const selectedKey = ref<string>()
//表格是否加载中
const loading = ref<boolean>(false)
//保存表单
const saveForm = ref<any>()
//查询条件表单
const searchForm = ref<any>()
//是否显示更新窗口
const visibleSaveLayer = ref<boolean>(false)
//是否显示详情窗口
const visibleInfoLayer = ref<boolean>(false)
//新增/编辑窗口标题
const saveLayerTitle = ref<string>()
//查询条件数据
const searchModel = ref<any>({})
//保存数据
const saveModel = ref<any>({})
//详情数据
const infoModel = ref<any>({})
//菜单列表数据
const menuList = ref<any>([])
//菜单id列表数据
const menuIdsList = ref<any>([])
//是否显示分配菜单权限窗口
const visibleAssigningMenusLayer = ref<boolean>(false)

//分页参数数据
const page = reactive<any>({
  current: 1,
  limit: 10, 
  total: 0 
})

//排序参数数据
const sortQuery = reactive<any>({
  sortField:'createTime',
  sortType:'desc'
})

//分配菜单权限保存数据
const assignedMenuModel= reactive<any>({
  roleId:null,
  menuIds:[]
})

//表格字段
const columns = ref<any[]>([
  { title: '序号', width: '30px', type: 'radio', fixed: 'left',hide:"true"},
  { title: '角色标识', width: '60px', key: 'roleCode', sort: 'desc'},
  { title: '角色名称', width: '60px', key: 'roleName', sort: 'desc'},
  { title: '类型', width: '80px', key: 'typeName', sort: 'desc'},
  { title: '备注', width: '100px', key: 'remark',ellipsisTooltip:"true"},
  { title: '创建人', width: '80px', key: 'createUserName'},
  { title: '创建时间', width: '100px', key: 'createTime'},
  { title: '操作', width: '120px', key: 'operator',fixed: 'right',customSlot: 'operator'}
])

//保存表单验证规则
const saveFormRules = ref<Rules>({
  roleCode : {
    type :  'string',
    min : 1,
    max : 20
  },
  roleName : {
    type :  'string',
    min : 1,
    max : 30
  },
  remark : {
    type :  'string',
    max : 100
  }
})

//保存窗口按钮
const saveLayerBtn = ref([{
    text: "提交",
    callback: () => {
      //提交要保存的数据
      saveForm.value.validate((isValidate: any, model: any, errors: any) => {
        if(!isValidate){
          return;
        } 
        saveApi(model).then(({ data, code, msg }) => {
          if (code == 200) {
            visibleSaveLayer.value = false
            search();
          }
        })
      })
    }
},{
    text: "取消",
    callback: () => {
      //关闭保存窗口
      saveForm.value.reset()
      visibleSaveLayer.value = false
    }
}])


//详情窗口按钮
const infoLayerBtn = ref([{
    text: "关闭",
    callback: () => {
      //详情窗口关闭
      visibleInfoLayer.value = false
    }
}])


//查询数据
const search = async() => {
  loading.value = true
  await loadDataSource();
  loading.value = false
}

//排序查询
const sortChange = (sortField: string, sortType: string) => {
  if(sortType){
    sortQuery.sortField = sortField;
    sortQuery.sortType = sortType;
    //查询数据
    search();
  }
}

//导出数据
const exportData = () => {
  loading.value = true
  exportApi(Object.assign(searchModel.value,{pageNum:page.current,pageSize:page.limit},sortQuery));   
  loading.value = false
}

//清除查询条件
const searchReset = () => {
  searchForm.value.reset();
}


//显示保存窗口
const toSave = (text: any, row?: any) => {
  saveLayerTitle.value = text
  if (row) {
      infoApi(row.id)
      .then(({ data, code, msg }) => {
        if (code == 200) {
          saveModel.value = data;
          //显示保存窗口
          visibleSaveLayer.value = true
        }
      })
    } else {
      saveModel.value = {}
      //显示保存窗口
      visibleSaveLayer.value = true
    }
}


//显示详情窗口
const toInfo = (row: any) =>{
  infoApi(row.id)
    .then(({ data, code, msg }) => {
      if (code == 200) {
        infoModel.value = data;
        visibleInfoLayer.value = true
      }
    }) 
}

//加载表格数据
const loadDataSource = () => {
return new Promise<void>((resolve) => {
  let queryParam = Object.assign(searchModel.value,{pageNum:page.current,pageSize:page.limit},sortQuery);
  pageApi(queryParam)
    .then(({ data, code, msg }) => {
      if (code == 200) {
        dataSource.value = data.list;
        page.total = data.total;
      }
    }).finally(()=>{
        resolve();
    })
  })
}

//删除数据
const remove = (row:any) => {
  layer.confirm(`确认删除角色[${row.roleName}]？`, {
    title: '提示',
    btn: [{
        text: '确定',
        callback: (id: any) => {
          removeApi(row.id).then(({ data, code, msg }) => {
            if (code == 200) {
              layer.msg('删除成功!')
              layer.close(id)
              search();
            } 
          })
        }
      },{
        text: '取消',
        callback: (id: any) => {
          layer.close(id)
        }
      }]
  })
}

//显示分配菜单权限窗口
const toAssigningMenus = (row: any)=>{
  assignedMenuModel.roleId = row.id
  //查询菜单列表
  treeApi(null)
  .then(({ data, code, msg }) => {
      if (code == 200) {
        menuList.value = data
        //查询用户已分配菜单
        queryAssignedMenuApi(row.id)
        .then(({ data, code, msg }) => {
          if (code == 200) {
            assignedMenuModel.menuIds = data;
            //显示窗口
            visibleAssigningMenusLayer.value = true;
          }
        })
      }
    })

}


//分配菜单权限窗口按钮
const assigningMenusLayerBtn = ref([{
    text: "提交",
    callback: () => {
      //提交数据
      assigningMenusApi(assignedMenuModel)
      .then(({ data, code, msg }) => {
        if (code == 200) {
          visibleAssigningMenusLayer.value = false
          search();
        }
      })
    }
},{
    text: "取消",
    callback: () => {
      //关闭窗口
      visibleAssigningMenusLayer.value = false
    }
}])

</script>

<style scoped>

</style>../../../api/module/sys-role